package org.webcat.electronicsubmissionplugin.wizard;

import org.webcat.electronicsubmissionplugin.model.LongRunningTask;
import java.awt.Component;
import java.awt.Cursor;
import javax.swing.event.ChangeListener;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.WizardDescriptor;
import org.openide.WizardValidationException;
import org.openide.util.HelpCtx;
import org.webcat.electronicsubmissionplugin.model.SubmitterModel;
import org.webcat.submitter.targets.SubmissionTarget;
import org.webcat.electronicsubmissionplugin.utils.MessageUtil;

/**
 * Handles the validating and communication between the model this panel's
 * corresponding view {@link SubmitVisualPanel1}.
 * @author rob44, rstodd13, samccarn
 */
@SuppressWarnings("rawtypes")
public class SubmitWizardPanel1 implements WizardDescriptor.ValidatingPanel {

    /**
     * The visual component that displays this panel. If you need to access the
     * component from this class, just use getComponent().
     */
    private SubmitVisualPanel1 component;
    private SubmitterModel model = SubmitterModel.getInstance();

    /**
     * Gets the component to display.
     * @return the component
     */
    public Component getComponent() {
        if (component == null) {
            component = new SubmitVisualPanel1();
        }
        return component;
    }

    /**
     * Gets the help context. Unused.
     * @return the help context
     */
    public HelpCtx getHelp() {
        // Show no Help button for this panel:
        return HelpCtx.DEFAULT_HELP;
        // If you have context help:
        // return new HelpCtx(SampleWizardPanel1.class);
    }

    /**
     * If set to false, next button will become unclickable.
     * Validation is performed when the user clicks next, so next must always be clickable.
     * Unused.
     * @return true
     */
    public boolean isValid() {
        return true;
    }

    /**
     * Unused
     * @param l
     */
    public final void addChangeListener(ChangeListener l) {
        // unused
    }

    /**
     * Unused.
     * @param l
     */
    public final void removeChangeListener(ChangeListener l) {
        // unused
    }
    /*
    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
    public final void addChangeListener(ChangeListener l) {
    synchronized (listeners) {
    listeners.add(l);
    }
    }
    public final void removeChangeListener(ChangeListener l) {
    synchronized (listeners) {
    listeners.remove(l);
    }
    }
    protected final void fireChangeEvent() {
    Iterator<ChangeListener> it;
    synchronized (listeners) {
    it = new HashSet<ChangeListener>(listeners).iterator();
    }
    ChangeEvent ev = new ChangeEvent(this);
    while (it.hasNext()) {
    it.next().stateChanged(ev);
    }
    }
     */

    /**
     * Uses the model to read saved settings. Use ({@link WizardDescriptor}) settings to
     * store intra-panel data.
     * @param settings the wizard descriptor
     */
    public void readSettings(Object settings) {
        component.getProjectNameLabel().setText(model.getLastProjectSubmitSelect());
        component.getUsernameTextField().setText(model.getUsername());
        // do LRT here
        LongRunningTask lrt = new LongRunningTask() {

            ProgressHandle handle = ProgressHandleFactory.createHandle("Retrieving Submission Targets");

            @Override
            public void onError(Exception ex) {
                MessageUtil.error("Unable to retieve targets. Be sure you've entered the correct URL");
                component.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                component.getSubmissionTree().setVisible(false); // show the tree
                handle.finish();
            }

            @Override
            public void taskToRun() throws Exception {
                handle.switchToIndeterminate();
                handle.progress("Fetching targets.");
                component.getSubmissionTree().setModel(model.getTreeModel());
                component.getSubmissionTree().expandForPaths(model.getLastExpandedTreePaths());
            }

            @Override
            public void onSuccessfulComplete() {
                component.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                handle.progress("Targets retrieved.");
                handle.finish();
                component.getSubmissionTree().setVisible(true); // show the tree

            }

            @Override
            public void beforeStart() {
                handle.start();
                component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                component.getSubmissionTree().setVisible(false); // hide the tree while loading
            }
        };
        model.runLongRunningTask(lrt);
        component.setProjectsList(model.getProjectsList());
    }

    /**
     * Uses the model to store available settings.
     * @param settings
     */
    public void storeSettings(Object settings) {
        model.setUsername(component.getUsernameTextField().getText());
        model.setPassword(new String(component.getPasswordTextField().getPassword()));
        model.setProjectToSubmit(component.getProjectNameLabel().getText());
        model.setSubmitTarget((SubmissionTarget) component.getSubmissionTree().getLastSelectedPathComponent());
        model.setLastExpandedTreePaths(component.getSubmissionTree().getCurrentExpandedPathNames());

    }

    /**
     * Called when the "next" button in the wizard is clicked.
     */
    public void validate() throws WizardValidationException {
        // validate the view
        if (!component.validateFields()) {
            throw new WizardValidationException(null, component.getInvalidMessage(), null);
        }
    }
}
